package com.sunnada.nginx.bean.nginx.http;

import com.github.odiszapc.nginxparser.NgxBlock;
import com.github.odiszapc.nginxparser.NgxEntry;
import com.github.odiszapc.nginxparser.NgxParam;
import com.github.odiszapc.nginxparser.NgxToken;
import com.sunnada.nginx.common.NginxUtils;
import com.sunnada.nginx.exception.CustonException;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Data
public class Location {
    /**
     * 监听的服务器
     */
    @ApiModelProperty(hidden = true)
    private String serverName;
    /**
     * 监听的接口
     */
    @ApiModelProperty(hidden = true)
    private String serverPort;
    /**
     * 映射规则
     */
    @ApiModelProperty(value = "映射规则")
    private String path;
    /**
     * 映射类型：
     * root
     * alias
     * proxy_pass
     */
    @ApiModelProperty(value = "映射类型")
    private String mapType;
    /**
     * 映射路径
     */
    @ApiModelProperty(value = "映射路径")
    private String mapPath;
    /**
     * 映射头
     */
    @ApiModelProperty(value = "映射头列表")
    private List<ProxySetHeader> proxyHeaders = new ArrayList<>();

    public Location(){};

    public Location(String serverName,String serverPort,NgxBlock block){
        this.serverName = serverName;
        this.serverPort = serverPort;
        this.path = StringUtils.join(block.getValues()," ");
        Collection<NgxEntry> entries = block.getEntries();
        for (NgxEntry entry : entries) {
            NgxParam param = (NgxParam) entry;
            if (!(entry instanceof NgxParam)) continue;
            if ("root".equals(param.getName()) ||
                "alias".equals(param.getName())||
                "proxy_pass".equals(param.getName())){
                this.mapType = param.getName();
                this.mapPath = param.getValue();
            }
            if ("proxy_set_header".equals(param.getName())){
                proxyHeaders.add(new ProxySetHeader(param.getValues().get(0),param.getValues().get(1)));
            }
        }
    }

    public void addProxyHeaders(ProxySetHeader proxySetHeader){
        proxyHeaders.add(proxySetHeader);
    }

    /**
     * 将对象转为NgxBlock对象
     * @return
     */
    public NgxBlock toNgxBlock(){
        NgxBlock block = new NgxBlock();
        block.addValue(new NgxToken(getToken()));
        block.addValue(path);
        for (ProxySetHeader proxyHeader : proxyHeaders) {
            block.addEntry(proxyHeader.toNgxParam());
        }
        block.addEntry(mapToNgxParam());
        return block;
    }

    private NgxParam mapToNgxParam(){
        NgxParam ngxParam = new NgxParam();
        ngxParam.addValue(mapType);
        ngxParam.addValue(mapPath);
        return ngxParam;
    }

    public String getToken(){
        return "location";
    }



    /**
     * 校验这个对象的有效性
     * @return
     */
    public boolean vali() throws CustonException {
        if (StringUtils.isBlank(path)) throw new CustonException("映射规则不能为空");
        if (StringUtils.isBlank(mapType)) throw new CustonException("映射方式不能为空");
        if (StringUtils.isBlank(mapPath)) throw new CustonException("映射路径不能为空");
        if (!mapType.equals("root")&&!mapType.equals("alias")&&!mapType.equals("proxy_pass"))
            throw new CustonException("映射方式必须为root/alias/proxy_pass中的一种");
        return true;
    }
}
